在线编程--汉诺塔问题

题目描述

对于传统的汉诺塔游戏我们做一个拓展,我们有从大到小放置的n个圆盘,开始时所有圆盘都放在左边的柱子上,按照汉诺塔游戏的要求我们要把所有的圆盘都移到右边的柱子上,请实现一个函数打印最优移动轨迹。
给定一个int n,表示有n个圆盘。请返回一个string数组,其中的元素依次为每次移动的描述。描述格式为: move from [left/mid/right] to [left/mid/right]。
测试样例:
1
返回:move from left to right

import java.util.*;

public class Hanoi {
    static ArrayList<String> arr=new ArrayList<String>();
    public ArrayList<String> getSolution(int n) {
        // write code here
        String left="left";
        String mid="mid";
        String right="right";
        hanoiProblems(n,left, mid, right);
        return arr;
    }
    public enum Action{
        No,LToM,MToL,MToR,RToM
    }
    public int hanoiProblems(int n,String left,String mid,String right){
        Stack<Integer> ls=new Stack<Integer>();
        Stack<Integer> ms=new Stack<Integer>();
        Stack<Integer> rs=new Stack<Integer>();
        ls.push(Integer.MAX_VALUE);
        ms.push(Integer.MAX_VALUE);
        rs.push(Integer.MAX_VALUE);
        for(int i=n;i>0;i--){
            ls.push(i);  //将数字压入栈内
        }   
        Action[] record={Action.No};
        int step=0;
        while(rs.size()!=n+1){
            step+=fStackTotStack(record, Action.MToL, Action.LToM, ls, ms, left, mid);
            step+=fStackTotStack(record, Action.LToM, Action.MToL, ms, ls, mid, left);
            step+=fStackTotStack(record, Action.RToM, Action.MToR, ms, rs, mid, right);
            step+=fStackTotStack(record, Action.MToR, Action.RToM, rs, ms, right, mid);         
        }
        return step;
     }

     public static int fStackTotStack(Action[] record,Action preNoAct,Action nowAct,Stack<Integer> fStack,Stack<Integer> tStack, String from,String to){
        if(record[0]!=preNoAct&&fStack.peek()<tStack.peek()){
            tStack.push(fStack.pop());
            arr.add("Move "+tStack.peek()+" from "+from+" to "+to);
            record[0]=nowAct;
            return 1;
        }
        return 0;
     }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值